<?php
global $CFG;
require_once(dirname(__FILE__).'/../../resourcepage_extension_pull.php');
require_once(dirname(__FILE__).'/../../../../lib/snoopy/Snoopy.class.inc');
require_once($CFG->dirroot.'/local/references/convert/refxml.php');
require_once($CFG->dirroot.'/local/references/apibib/apibib_lib.php');
require_once($CFG->dirroot.'/local/references/linking.php');

class resourcepage_rssfeed extends resourcepage_extension_pull {


    private $application = false;
    private $text = false;
    private $xml = false;

    private $atom = false;
    private $rss = false;
    private $rdf = false;

    private $unknown = false;

    private $charset = false;

    private $encoded = false;
    private $contenttypefound = false;

    private $feedtype;
    private $knownfeedtype = false;

    private $checkonly = false;





    // rss feeds defy the www3c standards on encoding



    public function get_database_version() {
        return '2007022800';
    }



    public function set_checkonly($setting) {

        GLOBAL $checkonly;

        $checkonly = $setting;


    }



    public function get_checkonly() {

        GLOBAL $checkonly;

        return $checkonly;


    }

    // place functions to deal with known bespoke types here

    // bespoke feed function that require changing to allow for updating



    function check_for_bespoke_feedtypes($url) {

        $feedtype = '';


        // leave empty unless you have a bespoke feed




        return $feedtype;


    }



    function check_possible_bespoke_feed($str) {

        GLOBAL $feedtype, $knownfeedtype;

        $feedtype = '';

        // leave empty unless we need to check for bespoke feeds
        // if checking for a bespoke feed and feed type is found set $feedtype to feedtype
        // and set $knowfeedtype to true







        // need to return $feedtype regardless of possible results

        return $feedtype;


    }


    /**
     * Creates bespoke feed types in the db
     * updated by JP5987
     * @param $container
     * @param $nextupdate
     * @param $plugininfo
     * @param $snoopy
     * @param $feedtype
     * @param $includetitle
     * @return boolean
     */
    function update_bespoke_feed($container,&$nextupdate,&$plugininfo, $snoopy, $feedtype, $includetitle) {

        // leave empty unless we need to update bespoke feeds


        //jp5987 - REFWORKS TYPE ("sub-type" of RDF)
        //creates "reference" types
        if($feedtype=='REFWORKS'){

            $actiontaken = false;

            // check to see whether this is purely a check of possible content
            $walkthrough = $this->get_checkonly();

            $tw=null;
            if(! $walkthrough) {
                $tw=new transaction_wrapper();

                // OK, clear existing items...
                $this->resourcepage->delete_contained_items($container);
            }

            //instance of ref xml management class
            $refman=new refxml();

            //load feed into dom + check
            $dom = new DOMDocument();
            $dom->preserveWhiteSpace = false;
            $dom->formatOutput = false;
            if(!$dom->loadXML($snoopy->results)){
                throw new Exception('Incompatible rss feed.');
            }
            //clear snoopy var - saves mem?
            unset($snoopy);

            if($refman->test_data_type(&$dom,'RefWorksRSS')===false){
                throw new Exception('Incompatible rss feed.');
            }

            //get title + items
            $title = $dom->getElementsByTagName('title')->item(0)->nodeValue;

            //Add title?
            if( (strlen($title) > 0) && ($includetitle) && (!$walkthrough) ) {
                // decode html special characters in the title
                $title = htmlspecialchars_decode($title,ENT_QUOTES);

                $i1=$this->resourcepage->add_item('text',false,null,null,null,$title, null,null,null,null,null);

                // Add the link between our container and the item
                $this->resourcepage->add_container_item($container,$i1);

                $actiontaken = true;
            }

            //set number of items to display to max
            $numberoflinks=$dom->getElementsByTagName('item')->length;

            //work out max num of entries to display
            // Get settings from database
            if(!is_object($container)) {

                $record=$this->get_maintable_record($container);

                // get the number of item to be displayed
                $numberoflinks_rec = 0;
                $numberoflinks_rec = $record->numberoflinks;

                if( ($numberoflinks_rec != 0 && $numberoflinks_rec != '') && ($numberoflinks > $numberoflinks_rec) ) {
                    // set number of items to be displayed to number of links specified
                    $numberoflinks = $numberoflinks_rec;
                }

            }

            //Step 1.
            //Convert rss feed into a reference data xml
            //First check if we can convert the data from rss xml to a standard format
            //This makes data handling on export (user activity) quicker


            $refxml=false;
            //when converting rss, sort by title
            $refxml=$refman->return_transform_in($dom,'RefWorksRSS','title');
            //clear initial data vars, as no longer needed.
            unset($dom);
            unset($xpath);
            if($refxml===false)
            {
                throw new Exception('Errror processing RSS feed');
            }


            //Step 2
            //Get full title references from QuikBib using step 1 data

            //db call - get module inst refstyle, (cur mod id from container table)
            global $CFG, $db, $COURSE;

            $rs=new stdClass;
            $conid=0;
            $modid=0;
            if(!is_object($container) && $container!=0 && $container!=NULL){
                $conid=$container;
            }else{
                //coming from add/update ui
                $conid=required_param('containerid',PARAM_INT);
            }
            if($conid==0){
                //no container set (e.g. new item)
                $module=module_resourcepage::$inst;

                $module->obtain_view_info(required_param('coursemodule',PARAM_INT),null,$cm,$course,$resourcepage);

                $modid=$resourcepage->id;
            }else{

                $modid=get_field('resourcepage_containers','resourcepageid','id',$conid);
            }


            if(!$teststyle=get_field('resourcepage','refstyle','id',$modid)){
                $teststyle=0;
            }
            //convert refstyle from int into text
            $teststyle=apibib::$referencestyles[$teststyle]['string'];

            //get the data string to send to quikbib
            $refstring=$refman->return_references($refxml,true);

            //get reference titles from apibib
            $titles=apibib::getbib($refstring, $teststyle,'RefWorks XML');
            if(!is_array($titles)){
                $titles=array();
            }

            //get data for each item
            $alldata=$refman->return_reference($refxml,array(),true,true);
            if($alldata===false){
                $alldata=array();
            }
            //Step 7
            //Work out weblink for each item
            //work out if we need to send the course name to the link as this is used to rack where links come from
            $coursename = '';
            if(isset($COURSE->id) && $COURSE->id == SITEID) {
                //in cron job - don't know course id, so get from db using $modid
                if($modid>0){
                    if($courseid=get_field('resourcepage','course','id',$modid)){
                        $coursename = get_field('course','shortname','id',$courseid);
                    }
                }
            }
            //Step 8
            //Create resource page "reference" items
            if(!$walkthrough)
            {

                //loop thru items (against numberoflinks)
                for($a=0;$a<$numberoflinks;$a++)
                {
                    $data='';
                    if(array_key_exists($a,$alldata)){
                        $data=$alldata[$a];
                        $document=DOMDocument::loadXML($data); //prepare for creation of weblink
                        $linking = linking::create_link($document, $coursename); //create weblink
                    }

                    $title='';
                    if(array_key_exists($a,$titles)){
                        $title=$titles[$a];
                    }


                    //description
                    $desc = '';
                    $notes = $document->getElementsByTagName('no');
                    if($notes->length > 0){
                        $noteval = $notes->item(0)->nodeValue;
                        $desc = clean_text($noteval, FORMAT_HTML);
                    }

                    $weblink=$linking[0];
                    //create "reference" item

                    $i1=$this->resourcepage->add_item('reference',false,null,null,null,$title,$desc,null,$weblink,null,null,null,null,null,null,$data);

                    // Add the link between our container and the item
                    $this->resourcepage->add_container_item($container,$i1);
                }
            }

            //we've added some items - so set action true
            if(!$walkthrough && $numberoflinks>0){
                $actiontaken=true;
            }


            //commit?
            if(! $walkthrough && $actiontaken===true) {
                $tw->commit();
            } // endif


        }




        return $actiontaken;



    }



    function get_bespoke_encoding($url, $headers, $str) {

        GLOBAL $feedtype;

        $encoding = '';
        $feedtype = '';


        // leave empty unless  we need to get bespoke encoding


        return $encoding;

    }

    // normal stuff



    function check_url_for_rss($url) {

        // the url should be standard format for rss of the type

        $feedtype = '';
        $num = 0;

        if(preg_match('/(rss)/imsx', $url, $possiblerss)) {

            // if a rss feed found it will be in substring

            $num = count($possiblerss[0]);

            $feedtype = strtoupper($possiblerss[0]);

        }


        return $feedtype;

    }







    function check_url_for_feedtype($url) {

        $feedtype = '';


        // check bespoke feed types - the chances arte they will override any form of standard feedtypes

        $feedtype = $this->check_for_bespoke_feedtypes($url);

        if(strlen($feedtype) > 0) {

            // have a feed type

        } else {


            // check to see whether a rss feed

            $feedtype = $this->check_url_for_rss($url);

        } // endif


        return $feedtype;


    }





    public function get_rss_feed_encoding($url, $headers, $str) {

        GLOBAL $feedtype;

        $encoding = '';
        $feedtype = '';


        $encoding = $this->get_bespoke_encoding($url, $headers, $str);

        if(strlen($encoding) == 0) {  // nothing found

            // try to get encoding from xml declarations
            $encoding = @$this->get_encoding_from_xml_declaration($str);

            if(strlen($encoding) == 0) {  // nothing found

                $encoding = $this->get_encoding_from_content_type($headers);

            } else {

                $encoded = true;

            } // endif


        } else {

            $encoded = true;

        }


        // print '<pre> feed type is '.$feedtype.'</pre>';
        // print '<pre> encoding from get rss feed encoding is '.$encoding.'</pre>';

        return $encoding;


    }






    // pick up encoding from the charset parameter in the header if possible
    // need to application type i.e application/xml or text/xml and signify that it is xml
    // get rss type i.e. rss/dublin core or atom

    function get_encoding_from_content_type($headers) {

        $numberheaders = count($headers);

        GLOBAL  $application, $text,  $xml, $knownfeedtype, $feedtype, $atom, $rss, $rdf, $unknown, $charset, $encoded, $contenttypefound;

        $encoding = '';
        $feedtype = '';


        for($i=0; $i < $numberheaders; $i++) {

            // check for content type

            if (preg_match("/^[Cc]ontent-[Tt]ype/", $headers[$i])) {

                $contenttypefound = true;

                // need to get content type

                if(preg_match("/application/i", $headers[$i])) {

                    $application = true;

                } else {

                    if(preg_match("/text/i", $headers[$i])) {

                        $text = true;

                    } else {

                        $unknown = true;

                    } // endif


                } // endif


                // need to find out whether content is xml


                if(preg_match("/xml/i", $headers[$i])) {

                    $xml = true;


                    // lets see whether it is an atom feed

                    if(preg_match("/atom/i", $headers[$i])) {

                        $atom = true;
                        $feedtype = 'ATOM';
                        $knownfeedtype = true;

                    } else {

                        // lets see whether it is an rss feed

                        if(preg_match("/rss/i", $headers[$i])) {

                            $rss = true;
                            $feedtype = 'RSS';
                            $knownfeedtype = true;

                        } else {

                            // lets see whether it is an rdf feed

                            if(preg_match("/rdf/i", $headers[$i])) {

                                $rdf = true;
                                $feedtype = 'RDF';
                                $knownfeedtype = true;

                            } // endif

                        } // endif

                    } // endif


                    // lets see if we can pick up the charset from content-type header

                    if(preg_match("/charset/i", $headers[$i])) {

                        $charset = true;


                        // do the hard grunt to get the char set


                        // charset=(["']*)([A-Za-z\-0-9]*)(["']*)/imsx
                        // works against Content-Type: application/xml charset=ISO-8859-1
                        // and Content-Type: application/xml charset="ISO-8859-1"
                        // tested by using the regex coach downloaded from http://weitz.de/regex-coach/
                        // returns an array with 4 columns including the entire match as the first column
                        // we need the 3rd column[2] that matches against ([A-Za-z\-0-9]*)

                        preg_match('/charset=(["\']*)([A-Za-z\-0-9]*)(["\']*)/imsx', $headers[$i], $contentencoding);

                        $encoding = $contentencoding[2];

                        if(strlen($encoding) == 0) {  // nothing found

                        } else {

                            $encoded = true;

                        } // endif


                    } // endif


                    if($text) {

                        // defaults to us-ascii which should be utf-8

                        $encoding = 'utf-8';
                        $encoded = true;

                    } // endif


                } // endif

                break;


            } // endif


        } // endfor loop


        // print '<pre> encoding from content type is '.$encoding.'</pre>';


        return $encoding;


    }



    // pick up the encoding from the xml declaration in the document itself


    function get_encoding_from_xml_declaration($str) {

        GLOBAL  $application, $text,  $xml, $atom, $rss, $rdf, $unknown, $charset, $encoded, $contenttypefound;

        $encoding = '';


        // lets pick it up from the xml declaration in the document itself
        // should produce 1+2 substrings

        preg_match_all('/<?xml (.*?) ?>/imsx', $str, $xmldeclarations);

        $columns = 0;

        $columns = count($xmldeclarations);

        for($i=0; $i<$columns; $i++) {

            // due to bum data being put in we need to check
            // to see whether xml declaration has been found
            // otherwise get out of here with encoding set to empty

            if( ! isset($xmldeclarations[$i][0]) ) {

                $encoding = '';

                break;

            }

            preg_match('/encoding=(["\']*)([A-Za-z\-0-9]*)(["\']*)/imsx', $xmldeclarations[$i][0], $contentencoding);

            $encodingcolumns = count($contentencoding);

            $encoding = !empty($contentencoding[2]) ? $contentencoding[2] : '';

            for($j=0; $j<$encodingcolumns; $j++) {

                if(strlen($encoding) == 0) {  // nothing found

                    // do nothing

                } else {

                    $encoded = true;

                    if($xml == false) {

                        $xml = true;

                    }

                    break;

                } // endif

            } // end $j loop

            if($encoded) {

                break;

            }


        } // end $i loop

        // print '<pre> encoding from xml declarations is '.$encoding.'</pre>';

        return $encoding;

    }


    function update_rssfeed($container,&$nextupdate,&$plugininfo, $snoopy, $includetitle) {

        $actiontaken = false;

        // check to see whether this is purely a check of possible content
        $walkthrough = $this->get_checkonly();

        // pick up page title, description and link, picks up main plus 3 substrings
        if( preg_match_all('/<channel(.*?)>(.*?)<item(.*?)>/imxs', $snoopy->results, $maindetails) > 0) {

            preg_match_all('/<link>(.*?)<\/link>/', $maindetails[2][0], $links);
            preg_match_all('/<description>(.*?)<\/description>/', $maindetails[2][0], $descriptions);

            $link=$links[1][0];
            $description=@$descriptions[1][0];

            $title = '';
            $titlewithtags = '';

            // for reasons of utter twattory make sure we get a title before printing it
            // may have a title or no title
            if(preg_match('/<title>(.*?)<\/title>/imxs', $maindetails[2][0], $titles) ) {
                $titlewithtags = $titles[0];
                $title = $titles[1];
            }

            // preg_match_all seems to return at least 2 arrays regardless
            preg_match_all('/<item>(.*?)<\/item>/mxs', $snoopy->results, $items);   // multi-line, ignore whitespace, include new lines,

            $numberitems = count($items[1]);

            $tw=null;
            if(! $walkthrough) {
                $tw=new transaction_wrapper();

                // OK, clear existing items...
                $this->resourcepage->delete_contained_items($container);
            }

            if( (strlen($title) > 0) && ($includetitle) ) {

                if(! $walkthrough) {

                    // decode wierd stuff
                    $doc = new DOMDocument();
                    if (@$doc->loadXML($titlewithtags)) {

                        // do nothing - we may need to save the xml

                    } else {

                        // lets get out of here with an error

                        // DO NOT CHANGE THIS MESSAGE - various other parts
                        // of code check for it with string compare (which
                        // is really bad practice but whatever, this probably
                        // shouldn't be an exception anyhow because an RSS feed
                        // with no items is perfectly legal).
                        $errormsg = 'No items found to be displayed';
                        throw new Exception($errormsg);
                    } // endif

                    $title = $doc->documentElement->firstChild->nodeValue;

                    // decode html special characters in the title
                    $title = htmlspecialchars_decode($title);

                    // add title
                    // after a bit more tidying up
                    $title = str_replace('&apos;', "'", $title);

                    $i1=$this->resourcepage->add_item('text',false,null,null,null,$title, null,null,null,null,null);

                    // Add the link between our container and the item
                    $this->resourcepage->add_container_item($container,$i1);

                } // endif

                $actiontaken = true;

            } // endif

            // ...and add new ones

            if($numberitems == 0) {

                // no items found
                // note: this code never gets entered because the original
                // check in huge if statement up there will have failed

            } else {

                // need to check for any limit attached to number of items to be displayed

                // Get settings from database
                if(!is_object($container)) {

                    $record=$this->get_maintable_record($container);

                    // get the number of item to be displayed

                    $numberoflinks = $record->numberoflinks;

                    if( ($numberoflinks == 0) || ($numberoflinks == '') ) {

                        // do nothing - assume all to be displayed

                    } else {

                        if($numberitems < $numberoflinks) {

                            // do nothing - there are fewer items to be displayed than links specified

                        } else {

                            // set number of items to be displayed to number of links specified

                            $numberitems = $numberoflinks;

                        } // endif

                    } // endif

                } // endif

                for($i=0; $i < $numberitems; $i++) {

                    // preg_match_all seems to return at least 2 arrays regardless
                    preg_match_all('/<link>(.*?)<\/link>/isx', $items[1][$i], $links);
                    preg_match_all('/<description>(.*?)<\/description>/isx', $items[1][$i], $descriptions);
                    preg_match_all('/<title>(.*?)<\/title>/isx', $items[1][$i], $titles);

                    $numberlinks = count($links[1]);  // previously 0
                    $numberdescriptions = count($descriptions[1]);  // previously 0
                    $numbertitles = count($titles[1]);  // previously 0

                    // even though we check assume that each item has only a single link, description and title
                    $titlewithtags = !empty($titles[0][0]) ? $titles[0][0] : '';
                    $link = !empty($links[1][0]) ? $links[1][0] : '';
                    $description = !empty($descriptions[1][0]) ? $descriptions[1][0] : '';

                    if(! $walkthrough) {

                        if($titlewithtags==='') {
                            $title='';
                        } else {
                            // decode wierd stuff
                            $doc = new DOMDocument();
                            if (@$doc->loadXML($titlewithtags)) {

                                // do nothing - we may need to save the xml

                            } else {

                                // lets get out of here with an error

                                // DO NOT CHANGE THIS MESSAGE - various other parts
                                // of code check for it with string compare (which
                                // is really bad practice but whatever, this probably
                                // shouldn't be an exception anyhow because an RSS feed
                                // with no items is perfectly legal).
                                $errormsg = 'No items found to be displayed';
                                throw new Exception($errormsg);

                            } // endif

                            $title = $doc->documentElement->firstChild->nodeValue;

                            // decode html special characters in the title
                            $title = htmlspecialchars_decode($title);
                        }

                        // tidy up an anomolies in the description if known
                        $patterns[0] = '/&lt;P&gt;/';
                        $patterns[1] = '/&lt;p&gt;/';

                        $description = preg_replace($patterns, '<br /><br />', $description);

                        // Fix up <br/> to make sure the closing slash is included
                        $description = preg_replace('/<br\s*>/', '<br />', $description);

                        // If there are more than two <br/>s in a row, replace with only two
                        $description = preg_replace('/(<br\s*\/>\s*){3,}/', '<br /><br />', $description);

                        // Add the item record
                        $rank=$i+1;

                        // A bit more tidying up
                        $title = str_replace('&apos;', "'", $title);
                        $description = str_replace('&apos;', "'", $description);
                        $description = html_entity_decode($description, ENT_COMPAT, 'UTF-8');
                        $link = str_replace('&amp;', '&', $link);

                        if($link=='') {

                            // is empty
                            $i1=$this->resourcepage->add_item('text',false,null,null,null,$title, $description,null,null,null,null);

                        } else {

                            // assume to be a web link
                            $i1=$this->resourcepage->add_item('weblink',false,null,null,null,$title, $description,null,$link,null,null);

                        } // endif

                        // Add the link between our container and the item
                        $this->resourcepage->add_container_item($container,$i1);

                    } else {

                        // assume we have found something and can now exit from for loop
                        break;

                    } // endif

                } // endfor

                $actiontaken = true;

            } // endif

            if(! $walkthrough) {
                $tw->commit();
            } // endif

        } else {
            // DO NOT CHANGE THIS MESSAGE - various other parts
            // of code check for it with string compare (which
            // is really bad practice but whatever, this probably
            // shouldn't be an exception anyhow because an RSS feed
            // with no items is perfectly legal).
            $errormsg = 'No items found to be displayed';
            throw new Exception($errormsg);
        } // endif

        return $actiontaken;
    }


    public function update($container,&$nextupdate,&$plugininfo) {

        GLOBAL  $application, $text,  $xml, $knownfeedtype, $feedtype, $atom, $rss, $rdf, $unknown, $charset, $encoded, $contenttypefound;

        $encoding = '';
        $feedtype = '';

        $errormsg = '';


        $url = '';
        $feedupdates = 0;


        $actiontaken = false;
        $walkthrough = false;
        $includetitle = false;


        // for dummy test purpose set check only to true


        // $this->set_checkonly(true);


        $actiontaken = false;


        // check to see whether this is purely a check of possible content

        $walkthrough = $this->get_checkonly();


        // Request another update in 1 hour and store updated time
        // $nextupdate=strtotime("+1 hour");
        // $plugininfo='Updated at '.date('r');

        $lastUpdatedTime = FALSE;
        if (strpos($plugininfo, 'Updated at ') !== FALSE) {
            $lastUpdatedTime = strtotime(str_replace('Updated at ', '', $plugininfo));
        }

        if(! $walkthrough) {

            // we need to set container properly rather than use a dummy container


            // Get settings from database
            $record=$this->get_maintable_record($container);

            // get the url

            $url = $record->word;
            $feedupdates = $record->feedupdates;
            $includetitle = $record->includetitle;

            // if statement code amended to force update if feedupdates is not set - see bug #3933
            if( ($feedupdates == '') || ($feedupdates == null) || (empty($feedupdates)) ){

                // nothing in feed updates - so set feed updates to default of a day

                $feedupdates = 24;

            }


            if($feedupdates > 0) {

                // Request another update in so many hour and store updated time

                $updateinhours = "+".$feedupdates." hour";
                $nextupdate=strtotime($updateinhours);
                $plugininfo='Updated at '.date('r');

            } else {

                // do nothing

                $nextupdate = '';


            } // endif


        } else {


            // this is a walk through

            $url = $container->word;


        } // endif


        // Initialise and set snoopy up

        $snoopy=new Snoopy;
        global $CFG;
        $snoopy->proxy_host=$CFG->proxyhost;
        $snoopy->proxy_port=$CFG->proxyport;


        /*
         // $url='http://newsrss.bbc.co.uk/rss/sportonline_uk_edition/football/rss.xml';

         // $url='http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/front_page/rss.xml';
         */

        //JP5987 - Special case to check if url is a refworks url - if so add param so all data is returned
        if((strpos($url,'http://www.refworks.com/refshare?site')!==false || strpos($url,'http://www.refworks.com/refshare/?site')!==false) && strpos($url,'&rss')){
            if(strpos($url,'&rss=true')===false){
                $url=str_replace('&rss','&rss=true',$url);
            }
            $url.='&basedate=01011900';
        }

        // call snoopy and hide its error messages

        @$snoopy->fetch($url);
        if(strlen($snoopy->error) > 0 ) {

            // we have an error - stop here


            $errormsg = 'the url \''.$url.'\' gives rise to the following error message '.$snoopy->error.' <br />Please check to see that \''.$url.'\' is a valid url address';

            $plugininfo = $errormsg;

            throw new Exception($errormsg);


        } else {

            $headers = $snoopy->headers;
            $response_code = trim($snoopy->response_code);

            // if snoopy response code returns 4xx code then set error message to invalid website address
            // and exit without doing anything


            // ([4][0-9][0-9])


            if(preg_match('/([4][0-9][0-9])/x', $response_code) ) {

                $plugininfo = 'the URL \''.$url.'\' is not accessible';

                $errormsg = $plugininfo;

                throw new Exception($errormsg);


            } else {


                // everything is okay and we can continue


                // print '<pre>feed type stind update is: '.$feedtype.'</pre>';


                $encoding = $this->get_rss_feed_encoding($url, $headers, $snoopy->results);


                // print '<pre> encoding is '.$encoding.'</pre>';


                if(strlen($encoding) == 0) {  // nothing found

                    // assume to be utf
                    $encoding = 'utf-8';
                    $encoded = true;


                } // endif


                // print '<pre> assumed encoding is '.$encoding.'</pre>';



                // encode to utf-8 if necessary


                if( ($encoding != 'utf-8') && ($encoding != 'UTF-8') ) {

                    $encoding = strtoupper($encoding);

                    // if the encoding is determined to be ISO-8859-1 set encoding to Windows-1252 instead.

                    if($encoding == 'ISO-8859-1') {

                        $encoding = 'Windows-1252';

                    } // endif



                    // print '<pre> encoding is '.$encoding.'</pre>';

                    // print '<pre>'.$snoopy->results.'</pre>';

                    // file_put_contents(dirname(__FILE__).'/../../../../../moodledata/pre_utf.txt', $snoopy->results);


                    $snoopy->results = mb_convert_encoding($snoopy->results, 'UTF-8', $encoding);


                    // file_put_contents(dirname(__FILE__).'/../../../../../moodledata/post_utf.txt', $snoopy->results);

                } // endif


                // print '<pre>feed type in update is: '.$feedtype.'</pre>';

                // print '<pre>'.$snoopy->results.'</pre>';

                // to handle those situations when we may need to reset the feedtype to something else
                // in order to process the the data according to another set of update routines - don't ask!!!


                if( ($feedtype != 'RSS') || ($feedtype != 'RDF') || ($feedtype != 'ATOM') ) {

                    // set knownfeedtype to false to allow for bespoke testing and possibly updating

                    $knownfeedtype = false;

                }





                // just check to see whether we can pick up feed type

                if(!$knownfeedtype) {

                    // check to see whether it is an rss feed

                    if(preg_match('/<rss(.*?)>/imxs', $snoopy->results) ) {

                        $rss = true;
                        $feedtype = 'RSS';
                        $knownfeedtype = true;

                    } else {

                        // check to see whether an rdf feed

                        if(preg_match('/<rdf(.*?)>/imxs', $snoopy->results) ) {

                            $rdf = true;
                            //reset other types as on cron job values remain from previous feeds
                            //Ideally would reset these at start of func - but not sure if needed there as knownfeedtype could already be true?
                            $rss=false;
                            $atom=false;
                            $feedtype = 'RDF';
                            $knownfeedtype = true;

                            //jp5987 - check for new RefWorks RSS type. This is an rdf (hence why code is here).
                            //Has namespace of xmlns:refworks="www.refworks.com/xml/"
                            if(strpos($snoopy->results,'xmlns:refworks="www.refworks.com/xml/"')){
                                $rdf=false;//ensure drop into bespoke
                                $feedtype = 'REFWORKS';
                            }


                        } else {


                            // check to whether an atom feed

                            if(preg_match('/(<feed(.?)xmlns(.*?)>)/imsx', $snoopy->results) ) {

                                $atom = true;
                                //reset other types as on cron job values remain from previous feeds
                                //Ideally would reset these at start of func - but not sure if needed there as knownfeedtype could already be true?
                                $rss=false;
                                $rdf=false;
                                $feedtype = 'ATOM';
                                $knownfeedtype = true;

                            } else {

                                // possibly a bespoke feed type

                                //print '<pre>'.htmlspecialchars($snoopy->results).'</pre>';

                                $feedtype = $this->check_possible_bespoke_feed($snoopy->results);

                                if(strlen($feedtype) > 0) {

                                    // we have a feed type - assume to be bespoke feed type

                                    $knownfeedtype = true;

                                }


                            } // endif


                        } // endif


                    } // endif


                } // endif


                // print '<pre> :::'.$feedtype.'</pre>';

                // print '<pre> known feed type is :::'.$knownfeedtype.'</pre>';

                // update according to feed type or try and update for known bespoke feed types




                if($knownfeedtype) {

                    /*
                     * Check if last update is greater than the RSS feed's expire date.
                     * If so, then the data we have is up-to-date; so do nothing and quit.
                     *
                     */
                    $last_modified = FALSE;
                    if ($lastUpdatedTime !== FALSE) {
                        foreach ($headers as $header) {
                            if (strpos($header, 'Last-Modified: ') !== FALSE) {
                                $last_modified = strtotime(substr(str_replace('Last-Modified: ', '', $header), 0, 26).' GMT');
                                if ($last_modified <= $lastUpdatedTime) {
                                    $last_modified = TRUE;
                                }
                            }
                        }
                        if ($last_modified) {
                            return TRUE;
                        }
                    }

                    // update according to feed type or try and update for known bespoke feed types

                    try {

                        if($rss) {


                            // rss feed type

                            $actiontaken = $this->update_rssfeed($container, $nextupdate, $plugininfo, $snoopy, $includetitle);


                        } else {


                            if($rdf) {


                                // rdf feed

                                // treat as a rss feed - probably using Dublin Core as its structure

                                $actiontaken = $this->update_rssfeed($container, $nextupdate, $plugininfo, $snoopy, $includetitle);


                            } else {


                                if($atom) {


                                    // atom feed


                                    // $actiontaken = $this->update_atomfeed($container, $nextupdate, $plugininfo, $snoopy, $includetitle);


                                } else {

                                    // bespoke feed

                                    $actiontaken = $this->update_bespoke_feed($container, $nextupdate, $plugininfo, $snoopy, $feedtype, $includetitle);

                                } // endif


                            } // endif


                        } // endif



                    } catch (Exception $e) {

                        $errormsg = $e->getMessage().' from '.$url;
                        $plugininfo = $errormsg;
                        throw new Exception ($errormsg);

                    } // end try-catch


                } else {


                    // print out dummy meesage

                    // print '<pre>'.htmlspecialchars($snoopy->results).'</pre>';
                    // print '<br><pre>unknown feed type</pre><br>';

                    // echo "<br>";
                    // echo "unknown feed type";
                    // echo "<br>";


                    $plugininfo = 'Could not read RSS data from '.$url.' - either the URL is incorrect or the '.
                            'result is not valid RSS.';

                    $errormsg = $plugininfo;

                    throw new Exception ($errormsg);


                } //endif


            } // endif


        } // endif


        return $actiontaken;


    }




}

?>
